;
; Esqueleto para programas em assembly (NASM)
; Plataforma alvo: arquivos objetos (OBJ/EXE) 16-bit (DOS)
;
; montar com a opcao -fobj
;


SEGMENT code                ; segmento de codigo
..start:                    ; ponto de entrada do programa
 
  mov  ax, data             ; inicializa DS
  mov  ds, ax

  mov  ax, stack            ; inicializa pilha (SS:SP)
  mov  ss, ax
  mov  sp, stacktop

  ;Leitura do N
  mov ah,0x01
  int 0x21
  
  ;Testar Tamanho
  ;Testa tipo Hexa x decimal
  cmp al,0x39
  ja TESTE_HEXA
  ;Decimal
  and al,0x0F
  jmp TESTA
  
  ;Hexa
  TESTE_HEXA:
  and al,0x0F
  add al,0x09
  
  TESTA:
  or al,0x00
  jz END
  
  
  ;Inicializa deixando bytes que nao serao usado no inicio do vetor
  mov dl,al           ;Copia do N
  mov bp,end_vetor-1  ;Ultima Posicao
  
  ;Ultimo Char
  mov dh,dl
  add dh,'a'-1
  
  ;Loop de inicializacao
  INIC_VET:
    mov [ds:bp],dh
    dec bp       ;Diminui Posicao
    dec dh       ;Diminui Caracter
    dec dl       ;Diminui Qunatidade a Inicializar
    jnz INIC_VET
  
  inc bp         ;DI fica Marcando Inicio do Vetor
  
  xor ah,ah
  mov dx,end_vetor
 
  call PERMUTACOES



  ;Final do Programa
  END:
  ;Imprime Fim de Linha e Nova Linha
  mov ah,0x02
  mov dl,0x0D
  int 0x21
  mov dl,0x0A
  int 0x21
  ; volta controle ao DOS
  mov  ah, 0x4C
  int  0x21

  ;Faz as permutacoes recursivamente
  ;Recebe em AX numero de bytes
  ;                 DI inicio do vetor verdadeiro
PERMUTACOES:
  push ax
  push bx
  push si
  push di
  push dx
  
  cmp ax,0x01
  ja PERMUTACOES_N_IMP
    mov ah,0x09
    mov dx,bp
	int 0x21
	jmp PERMUTACOES_RET
  PERMUTACOES_N_IMP:
  
  ;Inicializa Trocas
  ;Final do Vetor
  mov dx,end_vetor
  ;Primeiro Char do Sub-Vetor
  mov si,dx           
  sub si,ax
  ;Segundo Char do Sub Vetor
  mov di,si
  inc di
  
  ;Chama Recursao sem Fazer Nada
  dec ax          ;Novo tamanho do sub-vetor
  call PERMUTACOES
  
  ;Loop de Trocas
  PERMUTACOES_LOOP:
    ;Testa Validade
	cmp di,dx
	je PERMUTACOES_VETOR_RESET
  
    ;Troca
    mov bl,[si]
	mov bh,[di]
	mov [si],bh
	mov [di],bl
	
	;Desce
	call PERMUTACOES
  
    ;Posiciona Proxima Troca
	inc di
  
    ;Laco
	jmp PERMUTACOES_LOOP
  
  
  PERMUTACOES_VETOR_RESET:   ;Recoloca na Ordem Recebida shiftando vetor para esquerda
  dec dx        ;DX marca ultimo caracter
  mov bh,[si]
  
  ;Loop que shifta Sub-Vetor
  PERMUTACOES_VETOR_RESET_L:
    mov bl,[si+1]
    mov [si],bl
    inc si
    
    cmp si,dx
    jne PERMUTACOES_VETOR_RESET_L
  
  mov [si],bh
  
  PERMUTACOES_RET:
  pop dx
  pop di
  pop si
  pop bx
  pop ax
  ret
  
SEGMENT data                ; segmento de dados

vetor: resb 0x0F ; Vetor com 15 Posicoes
end_vetor: db " ",0x24 ;Marca Final do vetor com " $" para escrita do vetor na tela

SEGMENT stack stack        ; segmento de pilha
  RESB 256
stacktop:
